#include <linux/module.h>  /* __init __exit */
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>/* printk() */
#include <linux/delay.h>
...

static int first_drv_open(struct inode *inode,struct file *file)
{
    printk("first_drv_open\n");
    return 0;    
}
static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
    printk("first_drv_write\n");
    return 0;
}
static int  first_drv_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
       printk("first_drv_read\n");
    return 0;
}
/* 这个结构是字符设备驱动程序的核心
 * 当应用程序操作设备文件时所调用的open、read、write等函数，
 * 最终会调用这个结构中指定的对应函数
 */
static struct file_operations first_drv_fops = 
{
    .owner = THIS_MODULE,/* 这是一个宏，推向编译模块时自动创建的__this_module变量 */
       .open  = first_drv_open,
       .read = first_drv_read,
       .write = first_drv_write,
};
 /*模块加载函数，通过insmod命令加载模块时，被自动执行*/
static int __init first_drv_init(void)//驱动入口函数
{
    register_chrdev(111,"first_drv",&first_drv_fops);//注册一个主设备号为111的字符驱动设备 主设备号，设备名字，对应的结构体
    return 0;
}
/*模块卸载函数，当通过rmmod命令卸载时，会被自动执行*/
static void __exit first_drv_exit(void)
{
    unregister_chrdev(111,"first_drv");
}
/* 这两行指定驱动程序的初始化函数和卸载函数 */
module_init( first_drv_init);
module_exit(first_drv_exit);

MODULE_LICENSE("GPL");/*模块许可证明，描述内核模块的许可权限，必须*/